package com.eastidea.live.controller.rest;

import java.io.IOException;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.bson.types.ObjectId;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.eastidea.live.dao.AppDao;
import com.eastidea.live.dao.FormDao;
import com.eastidea.live.dao.UserDao;
import com.eastidea.live.entity.AppApplication;
import com.eastidea.live.entity.AppUser;
import com.eastidea.live.entity.FrmInfMultipleChoice;
import com.eastidea.live.entity.FrmInfMultipleOptions;
import com.eastidea.live.entity.FrmInfSingleLineText;
import com.eastidea.live.entity.FrmUiField;
import com.eastidea.live.entity.FrmUiForm;
import com.eastidea.live.field.multiplechoice.MultipleChoiceDao;
import com.eastidea.live.field.multiplechoice.MultipleChoiceOptionsDao;
import com.eastidea.live.field.multiplechoice.MultipleChoiceOptionsTo;
import com.eastidea.live.field.multiplechoice.MultipleChoiceOt;
import com.eastidea.live.field.multiplechoice.MultipleChoiceService;
import com.eastidea.live.field.multiplechoice.MultipleChoiceTo;
import com.eastidea.live.field.pagebreak.PageBreakOt;
import com.eastidea.live.field.pagebreak.PageBreakService;
import com.eastidea.live.field.pagebreak.PageBreakTo;
import com.eastidea.live.field.singleline.SingleLineTextDao;
import com.eastidea.live.field.singleline.SingleLineTextOt;
import com.eastidea.live.field.singleline.SingleLineTextService;
import com.eastidea.live.field.singleline.SingleLineTextTo;
import com.eastidea.live.ot.FormOt;
import com.eastidea.live.service.FormService;
import com.eastidea.live.to.AppTo;
import com.eastidea.live.to.FieldTo;
import com.eastidea.live.to.FormTo;
import com.eastidea.live.util.Constant;
import com.eastidea.live.util.QrUtil;
import com.eastidea.live.util.RequestUtil;
import com.eastidea.live.util.StringUtil;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
import com.mongodb.Mongo;
import com.mongodb.util.JSON;

@Controller
@SessionAttributes("user")
@RequestMapping(value = Constant.API_REST_V1 + "/forms")
public class FormRestController {

	@Resource
	AppDao appDao;
	@Resource
	UserDao userDao;

	@Resource
	FormDao formDao;
	@Resource
	SingleLineTextDao singleLineTextDao;
	@Resource
	MultipleChoiceDao multipleChoiceDao;
	@Resource
	MultipleChoiceOptionsDao multipleChoiceOptionsDao;

	@Resource
	FormService formService;
	@Resource
	PageBreakService pageBreakService;
	@Resource
	SingleLineTextService singleLineTextService;
	@Resource
	MultipleChoiceService multipleChoiceService;
	
	@RequestMapping(method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> list(@ModelAttribute("user") AppUser user, 
			HttpServletRequest request, ModelMap modelMap) throws Exception {		
		Map<String, Object> res = new HashMap<String, Object>();

		Long userId = user.getId();
		
		AppApplication app;
		if (StringUtil.isNotEmpty(request.getParameter("appId"))) {
			app = appDao.get(Long.valueOf(request.getParameter("appId")));
			request.getSession().setAttribute("app", app);
		} else {
			if (request.getSession().getAttribute("app") != null) {
				app = (AppApplication) request.getSession().getAttribute("app");
			} else {
				res.put("success", false);
				return res;
			}
		}
		Long appId = app.getId();
		
		Mongo mongo = new Mongo();
		DB db = mongo.getDB("palmio");
		boolean auth = db.authenticate("admin", "P2ssw0rd".toCharArray());
		System.out.println("auth: "+auth);
		DBCollection forms = db.getCollection("form");
		DBObject queryCondition = new BasicDBObject();
	    queryCondition.put("status", new BasicDBObject("$gt", 0));
	    queryCondition.put("userId", userId);
    	queryCondition.put("appId", appId);

		DBCursor cur = forms.find(queryCondition).sort(new BasicDBObject("updateTime", -1));

		List<DBObject> ls = cur.toArray();
		for (DBObject form: ls) {
			form.put("id", ((ObjectId) form.get("_id")).toString());
		}
		res.put("email", user.getEmail());
		res.put("frms", ls);
		res.put("appId", appId);
		return res;
	}

	@RequestMapping(value = "/{formId}", method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> detail(@ModelAttribute("user") AppUser user, @PathVariable("formId") String id, 
			HttpServletRequest request, ModelMap modelMap)
			throws UnknownHostException {
		Map<String, Object> res = new HashMap<String, Object>();
		
//		Object userObj = request.getSession().getAttribute("user");
//		if (userObj == null) {
//			res.put("success", false);
//			return res;
//		}
//		Long userId = ((AppUser)userObj).getId();

		Mongo mongo = new Mongo();
		DB db = mongo.getDB("palmio");
		boolean auth = db.authenticate("admin", "P2ssw0rd".toCharArray());
		System.out.println("auth: "+auth);
		DBCollection forms = db.getCollection("form");
		DBObject searchById = new BasicDBObject("_id", new ObjectId(id));
		DBObject formPo = forms.findOne(searchById);
		
//		if (!formPo.get("userId").toString().equals(userId.toString())) {
//			res.put("success", false);
//			return res;
//		}
		
		formPo.put("id", ((ObjectId) formPo.get("_id")).toString());		

		res.put("email", user.getEmail());
		
		res.put("frm", formPo);
		res.put("success", true);
		return res;
	}

	@RequestMapping(method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> save(@ModelAttribute("user") AppUser user, @RequestBody JSONObject jsonObj,
			HttpServletRequest request, ModelMap modelMap) throws UnknownHostException {
		Map<String, Object> res = new HashMap<String, Object>();

		Long userId = user.getId();
		
		DBObject form = (DBObject)JSON.parse(jsonObj.toString());
		form.removeField("id");
		form.put("userId", userId);
				
		form.put("updateTime", new Date());
		
		Mongo mongo = new Mongo();
		DB db = mongo.getDB("palmio");
		boolean auth = db.authenticate("admin", "P2ssw0rd".toCharArray());
		System.out.println("auth: "+auth);
		DBCollection forms = db.getCollection("form");
		forms.insert(form);
		
		String newId = ((ObjectId) form.get("_id")).toString();
		
		String path1 = "upload/qr/" + ((ObjectId) form.get("_id")).toString() + "-display.jpg";
		QrUtil.genQr(
				Constant.DISPLAY_ROOT + "index.html#/form/" + newId + "/display",
				RequestUtil.getAbsolutePath(request) + path1);
		form.put("displayQrCode", path1);
		
		forms.update(
            new BasicDBObject("_id", (ObjectId) form.get("_id")),
            form,
            false,
            false
	    );

		res.put("frmId", newId);
		res.put("success", true);
		return res;
	}

	@RequestMapping(method = RequestMethod.PUT)
	@ResponseBody
	public Map<String, Object> update(@ModelAttribute("user") AppUser user, @RequestBody JSONObject jsonObj,
			HttpServletRequest request, ModelMap modelMap) throws IOException {
		Map<String, Object> res = new HashMap<String, Object>();

		Long userId = user.getId();
		
		DBObject formDbo = (DBObject)JSON.parse(jsonObj.toString());
		ObjectId objId = new ObjectId(formDbo.get("id").toString());
		formDbo.removeField("id");
		
		Mongo mongo = new Mongo();
		DB db = mongo.getDB("palmio");
		boolean auth = db.authenticate("admin", "P2ssw0rd".toCharArray());
		System.out.println("auth: "+auth);
		DBCollection forms = db.getCollection("form");
		
		DBObject searchById = new BasicDBObject("_id", objId);
		DBObject formPo = forms.findOne(searchById);
		if (!formPo.get("userId").toString().equals(userId.toString())) {
			res.put("success", false);
			return res;
		}
		
		formDbo.put("updateTime", new Date());		
		forms.update(
            new BasicDBObject("_id", objId), 
            formDbo,
            false,
            false
	    );

		res.put("frmId", objId.toString());
		return res;
	}

	@RequestMapping(method = RequestMethod.DELETE)
	@ResponseBody
	public Map<String, Object> delete(@ModelAttribute("user") AppUser user, @RequestBody JSONObject jsonObj,
			ModelMap modelMap, HttpServletRequest request) throws IOException {
		Map<String, Object> res = new HashMap<String, Object>();

		Long userId = user.getId();
		
		DBObject formDbo = (DBObject)JSON.parse(jsonObj.toString());
		ObjectId objId = new ObjectId(formDbo.get("id").toString());
		formDbo.removeField("id");
		
		Mongo mongo = new Mongo();
		DB db = mongo.getDB("palmio");
		boolean auth = db.authenticate("admin", "P2ssw0rd".toCharArray());
		System.out.println("auth: "+auth);
		DBCollection forms = db.getCollection("form");
		
		DBObject searchById = new BasicDBObject("_id", objId);
		DBObject formPo = forms.findOne(searchById);
		if (!formPo.get("userId").toString().equals(userId.toString())) {
			res.put("success", false);
			return res;
		}
		
		formDbo.put("status", 0);
		formDbo.put("updateTime", new Date());
		
		forms.update(
            new BasicDBObject("_id", objId), 
            formDbo,
            false,
            false
	    );

		res.put("success", true);
		return res;
	}

}
